﻿namespace Blaze.Framework.LuaExtensions
{
    using System.Collections.Generic;
    using Pooling;
    using XLua;

    /// <summary>
    /// 为<see cref="LuaBehaviour"/>提供函数缓存。
    /// </summary>
    public class FunctionCache : IPoolable
    {
        public LuaTable LuaTable { get; set; }

        #region IPoolable Members

        public void OnGet()
        {
        }

        public void OnPut()
        {
            LuaTable = null;
        }

        #endregion

        public void Action<T>(string key, T content)
        {
            LuaFunction function;
            if (!mCache.TryGetValue(key, out function))
            {
                function = LuaTable.Get<LuaFunction>(key);
                mCache[key] = function;
            }

            if (function != null)
                function.Action(LuaTable, content);
        }

        public void Action(string key)
        {
            LuaFunction function;
            if (!mCache.TryGetValue(key, out function))
            {
                function = LuaTable.Get<LuaFunction>(key);
                mCache[key] = function;
            }

            if (function != null)
                function.Action(LuaTable);
        }

        public void Action<T1, T2, T3>(string key, T1 a1, T2 a2, T3 a3)
        {
            LuaFunction function;
            if (!mCache.TryGetValue(key, out function))
            {
                function = LuaTable.Get<LuaFunction>(key);
                mCache[key] = LuaTable.Get<LuaFunction>(key);
            }

            if (function != null)
                function.Action(LuaTable, a1, a2, a3);
        }

        public void Action<T1, T2, T3, T4>(string key, T1 a1, T2 a2, T3 a3, T4 a4)
        {
            LuaFunction function;
            if (mCache.TryGetValue(key, out function) && function != null)
                function.Action(LuaTable, a1, a2, a3, a4);
            else
                mCache[key] = LuaTable.Get<LuaFunction>(key);
        }

        public void Action(string key, string[] content)
        {
            LuaFunction function;
            if (mCache.TryGetValue(key, out function) && function != null)
                function.Action(LuaTable, content);
            else
                mCache[key] = LuaTable.Get<LuaFunction>(key);
        }

        public TResult Func<T1, TResult>(string key, T1 arg)
        {
            LuaFunction function;
            if (mCache.TryGetValue(key, out function) && function != null)
                return function.Func<LuaTable, T1, TResult>(LuaTable, arg);
            mCache[key] = LuaTable.Get<LuaFunction>(key);
            return default(TResult);
        }

        private readonly Dictionary<string, LuaFunction> mCache = new Dictionary<string, LuaFunction>(8);
    }
}